<?php
class RSA {
    /**
     * RSA constructor.
     * tip:只支持英文和数字,当密码长度超过117字节的时候,分割有问题
     */
    public function __construct(){
        // 判断openssl扩展存在
        extension_loaded('openssl') or die('openssl extension does not exist');
    }

    /**
     * 为站点创建公钥和私钥
     * wangruifang
     * 170512
     */
    public static function create_rsa_key(){
        $ok  = false;
        $config = array(
            "private_key_bits" => 1024,                     //字节数1024
            "private_key_type" => OPENSSL_KEYTYPE_RSA,     //加密类型
        );

        //创建公钥和私钥   返回资源
        $res = openssl_pkey_new($config);

        //从得到的资源中获取私钥
        openssl_pkey_export($res, $privKey);
        $pubKey = openssl_pkey_get_details($res);

        $ok = think\Db::connect(config('database.db_config2'))->name('Web')->where(['id'=>config('web_id')])->update(['public_key'=>$pubKey["key"],'private_key'=>$privKey]);
        if($ok!=false){
            rsa_key_cache();
        }
    }
    /**
     * rsa加密
     * @param string $str 原始明文
     * @return string
     */
    public static function encrypt($str) {
        $encrypt_data = '';
        $key = take_cache('rsa_key',false);
        if(!empty($key) && !empty($str)){
            try{
                foreach (str_split($str, 117) as $chunk) {
                    openssl_public_encrypt($chunk, $encryptData, $key['public_key']);
                    $encrypt_data .= $encryptData;
                }
                // 加密后 可以base64_encode后方便在网址中传输 或者打印  否则打印为乱码
                $encrypt_data = base64_encode($encrypt_data);
            }catch(Exception $e){
                return null;
            }
        }
        return $encrypt_data;
    }

    /**
     * rsa解密
     * @param string $str rsa密文
     * @return string
     */
    public static function decrypt($str){
        $key = take_cache('rsa_key',false);
        $decrypt_data = '';
        //解密
        if(!empty($str) && !empty($key)){
            try{
                foreach (str_split(base64_decode($str), 128) as $chunk) {
                    openssl_private_decrypt($chunk, $decryptData, $key['private_key']);
                    $decrypt_data .= $decryptData;
                }
            }catch(Exception $e){
                return null;
            }
        }
       return $decrypt_data;
    }
}
